package com.zdxlz.fcmp.upms.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdxlz.fcmp.common.core.exception.BizException;
import com.zdxlz.fcmp.upms.api.dto.SystemTenantDto;
import com.zdxlz.fcmp.upms.api.entity.SystemTenant;
import com.zdxlz.fcmp.upms.api.entity.SystemUser;
import com.zdxlz.fcmp.upms.api.mapper.SystemTenantMapper;
import com.zdxlz.fcmp.upms.api.mapper.SystemUserMapper;
import com.zdxlz.fcmp.upms.api.service.ISystemTenantService;
import com.zdxlz.fcmp.upms.api.vo.SystemTenantVo;
import jakarta.annotation.Resource;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.zdxlz.fcmp.common.core.constant.CommonConstants.ID;
import static com.zdxlz.fcmp.common.core.constant.CommonConstants.STATUS;
import static com.zdxlz.fcmp.common.core.constant.enums.ResCode.*;
import static com.zdxlz.fcmp.common.mybatis.enums.UserTypeEnum.TENANT;
import static com.zdxlz.fcmp.common.mybatis.enums.UserTypeEnum.USER;

/**
 * 租户信息表(SystemTenant)表服务实现类
 *
 * @author aman
 * @since 2025-02-24 10:46:51
 */
@Service
public class SystemTenantServiceImpl extends ServiceImpl<SystemTenantMapper, SystemTenant> implements ISystemTenantService {

    @Resource
    private SystemUserMapper systemUserMapper;

    @Override
    public IPage<SystemTenantVo> selectSystemTenant(Page<SystemTenant> page, SystemTenantDto dto) {
        LambdaQueryWrapper<SystemTenant> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(dto)) {
            queryWrapper
                    .eq(StrUtil.isNotBlank(dto.name()), SystemTenant::getName, dto.name())
                    .eq(StrUtil.isNotBlank(dto.contactMobile()), SystemTenant::getContactMobile, dto.contactMobile())
                    .eq(ObjectUtil.isNotEmpty(dto.status()), SystemTenant::getStatus, dto.status());
        }
        Page<SystemTenant> systemTenantPage = baseMapper.selectPage(page, queryWrapper);

        List<SystemTenantVo> systemTenantVos = systemTenantPage.getRecords().stream().map(this::convertToSystemTenantVo).collect(Collectors.toList());
        IPage<SystemTenantVo> tenantVoPage = new Page<>(systemTenantPage.getCurrent(), systemTenantPage.getSize(), systemTenantPage.getTotal());
        tenantVoPage.setRecords(systemTenantVos);
        return tenantVoPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertSystemTenant(SystemTenant entity, String password) {
        try {
            baseMapper.insert(entity);
        } catch (DataIntegrityViolationException e) {
            throw new DataIntegrityViolationException(TENANT_NAME_MOBILE_REPEAT.getReason(), e);
        }
        try {
            SystemUser systemUser = new SystemUser();
            systemUser.setTenantId(entity.getId());
            systemUser.setUsername(entity.getContactName());
            systemUser.setPassword(password);
            systemUser.setMobile(entity.getContactMobile());
            systemUser.setUserType(TENANT);
            systemUser.setEnableCaptcha(Boolean.FALSE);
            systemUser.setStatus(true);
            systemUserMapper.insert(systemUser);
        } catch (DataIntegrityViolationException e) {
            throw new DataIntegrityViolationException(TENANT_USER_MOBILE_REPEAT.getReason(), e);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSystemTenant(SystemTenant entity) {
        try {
            baseMapper.updateById(entity);
        } catch (DataIntegrityViolationException e) {
            throw new DataIntegrityViolationException(TENANT_NAME_MOBILE_REPEAT.getReason(), e);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSystemTenant(List<Integer> ids) {
        List<SystemTenant> systemTenants = baseMapper.selectByMap(Map.of(ID, ids.get(0), STATUS, true));
        if (CollectionUtil.isNotEmpty(systemTenants)) {
            throw new BizException(TENANT_ACTIVE_STATUS.getCode(), TENANT_ACTIVE_STATUS.getReason());
        }
        List<SystemUser> systemUserList = systemUserMapper.selectList(new LambdaQueryWrapper<SystemUser>().in(SystemUser::getTenantId, ids).in(SystemUser::getUserType, TENANT, USER));
        if (CollectionUtil.isNotEmpty(systemUserList)) {
            throw new BizException(TENANT_EXIST_USER.getCode(), TENANT_EXIST_USER.getReason());
        }
        baseMapper.deleteByIds(ids);
        return true;
    }

    private SystemTenantVo convertToSystemTenantVo(SystemTenant systemTenant) {
        SystemTenantVo systemTenantVo = new SystemTenantVo();
        BeanUtil.copyProperties(systemTenant, systemTenantVo);
        return systemTenantVo;
    }
}
